// ComputerEngine.h

#pragma once

#include "..\Engine\Engine.h"
#include "..\EngineManager\ThreadManagement.h"

#include "BitBoardConv.h"

using namespace System;
using namespace System::Threading;
using namespace System::ComponentModel;

namespace ComputerEngine {
	public enum class eBackgroundProcess { PreloadingDatabase, Thinking };

	public enum class eCheckersType { CzechCheckers, EnglishCheckers, InternationalCheckers, Unknown };

	public enum class eGameResult { WhiteWin, BlackWin, Draw, Unknown };

	public ref class BackgroundProcessEventArgs: public EventArgs
	{
	public:
		eBackgroundProcess BackgroundProcessType;
	};

	public ref class ProgressReportEventArgs: public EventArgs
	{
	public:
		int ProgressPercent;
	};

	public ref class MoveComputedEventArgs: public EventArgs
	{
	public:
		OutputBitBoard^ OutputBitBoard;
	};

	public enum class eSearchType { NegaMax, AlphaBeta, MTDf, PVS };

	
	[Serializable]
	public ref class EngineSettings {
	public:
		eSearchType SearchType;
		int MaxDepth;
		int MaxSeconds;
		bool UseCache;
		bool UseEndGameDB;
		bool UseKillerMoves;
		bool UseHistoryHeuristics;
		bool UsePositionStrategy;
		int CacheSizeMB;
	};


	public ref class Engine
	{
	public:
		Engine();

		void PreloadEndgameDatabase(String^ sEndGamePath, int cacheSizeInMB);
		bool LoadOpeningDatabase(String^ sOpeningPath);
		void TerminateComputer();

		void ComputeMove(eCheckersType checkersType, CheckersBoard^ board, bool bWhite, EngineSettings^ settings, array<OutputBitBoard^>^ gameHistory);

		// EGTB Viewer methods
		bool DBLookUpInit(String^ dbPath);
		eGameResult DBLookUp(CheckersBoard^ board, bool bWhite, int% dtm);
		void DBLookUpClose();
		eCheckersType GetEGTBDraughtType();
		int GetEGTBMaxPiece();

		// Engine Match Opening Probing
		int GetOpeningCount();
		array<OutputBitBoard^>^ GetOpeningByIndex(int index);

		// background process reporting
		event EventHandler<BackgroundProcessEventArgs^>^ BackgroundProcessInit;
		event EventHandler<ProgressReportEventArgs^>^ ProgressReport;
		event EventHandler^ BackgroundProcessFinished;
		event EventHandler<MoveComputedEventArgs^>^ MoveComputed;

	protected:
		static const int _maxPieces = 8;
		static const int _maxPiece = 8;
		static const int _maxRank = 7;

		CDbReader<_maxPieces, _maxPiece, _maxRank>* _pDbReader;

		EngineSettings^ _engineSettings;
			 
		Thread^ _backgroundThread;
		bool _bLoadingEndGameDB;

		SEngineSynch* m_pSynch;
		SEngineData* m_pCfg;

		void BackgroundThreadWorker();
		ManualResetEvent^ _backgroundThreadFinished; 

		static String^ _openingFile = gcnew String(L"opening.txt");
	};
}
